package com.simons.common.utils.file.office;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class ExcelFactory{
	
	private ExcelFactory(){
		// Do nothing because of 不能创建对象
	}

	public static AbstractExcel getExcel(File file) throws IOException{
		String fileName = file.getName();
		return getExcel(fileName);
	}
	
	public static AbstractExcel getExcel(String fileName) throws IOException {
		String extension = (fileName.lastIndexOf(".") == -1) ? "" : fileName.substring(fileName.lastIndexOf(".") + 1);

		AbstractExcel excel = null;
		if ("xls".equals(extension)) {
			excel = new Excel2003();
		} else if ("xlsx".equals(extension)) {
			excel = new Excel2007();
		} else {
			throw new IOException("不支持的文件类型");
		}
		
		return excel;
	}
	
	public static AbstractExcel getWriteExcel(String fileName) throws IOException{
		
		String extension = (fileName.lastIndexOf(".") == -1) ? "" : fileName.substring(fileName.lastIndexOf(".") + 1);

		AbstractExcel excel = null;
		if ("xls".equals(extension)) {
			
		} else if ("xlsx".equals(extension)) {
			excel = new Excel2007();
		} else {
			throw new IOException("不支持的文件类型");
		}
		
		return excel;
		
	}
	
	/**
	 * 分页导出到不同的sheet中的导出方法
	 * @throws Exception 
	 */
	public static <T> SXSSFWorkbook writeExcel2007Page(Workbook workbook, String fileName,String sheetName,String[] fieldNames, String[] heards, Collection<T> dataList) throws Exception{
		
		AbstractExcel excel = getWriteExcel(fileName);
		
		return excel.writeToWorkBook((SXSSFWorkbook)workbook, sheetName, fieldNames, heards, dataList);
	}
	
	/**
	 * 通过输出流做导出
	 * @param fileName
	 * @param out
	 * @param sheetName
	 * @param fieldNames
	 * @param heards
	 * @param dataList
	 * @throws Exception 
	 */
	public static <T> void writeExcel2007(String fileName,OutputStream out,String sheetName,String[] fieldNames, String[] heards, Collection<T> dataList) throws Exception{
		
		
		AbstractExcel excel = getWriteExcel(fileName);
		
		excel.write(out, sheetName, fieldNames, heards, dataList);
	}
	
	/**
	 * 通过输出流，并且有枚举类型的导出
	 * @param enumMap
	 * @param fileName
	 * @param out
	 * @param sheetName
	 * @param fieldNames
	 * @param heards
	 * @param dataList
	 * @throws Exception 
	 */
	public static <T> void writeExcel2007(Map<String, Map<String, String>> enumMap,String fileName,OutputStream out,String sheetName,String[] fieldNames, String[] heards, Collection<T> dataList) throws Exception{
		
		
		AbstractExcel excel = getWriteExcel(fileName);
		
		excel.writeByEnum(out, sheetName, fieldNames, heards, dataList, enumMap);
	}
	
	/**
	 * 通过文件做导出
	 * @param fileName
	 * @param sheetName
	 * @param fieldNames
	 * @param heards
	 * @param dataList
	 * @throws Exception 
	 */
	public static <T> void writeExcel2007(String fileName, String sheetName,String[] fieldNames, String[] heards, Collection<T> dataList) throws Exception{
		
		AbstractExcel excel = getWriteExcel(fileName);
		
		File file = new File(fileName);
		OutputStream out = new FileOutputStream(file);
		
		excel.write(out, sheetName, fieldNames, heards, dataList);
	} 
	
	/**
	 * 对外提供读取excel 的方法
	 * @throws Exception 
	 */
	public static <T> List<T> read(File file, String[] fieldNames, Class<T> calzz) throws Exception {
		AbstractExcel excel = getExcel(file);
		return excel.read(file, fieldNames, calzz);
	}
	
	/**
	 * 通过本地文件读取excel
	 * @param file
	 * @param sheetAt
	 * @param fieldNames
	 * @param calzz
	 * @return
	 * @throws Exception 
	 */
	public static <T> List<T> read(File file, int sheetAt, String[] fieldNames, Class<T> calzz) throws Exception {
		AbstractExcel excel = getExcel(file);
		return excel.read(file, sheetAt, fieldNames, calzz);
	}
	
	/**
	 * 通过inputstream读取excel
	 * @param input
	 * @param fileName
	 * @param sheetAt
	 * @param fieldNames
	 * @param calzz
	 * @return
	 * @throws Exception 
	 */
	public static <T> List<T> read(InputStream input, String fileName, int sheetAt, String[] fieldNames, Class<T> calzz) throws Exception {
		AbstractExcel excel = getExcel(fileName);
		return excel.read(input, sheetAt, fieldNames, calzz);
	}
	
	public static int getNumberOfSheets(File file) throws Exception{
		AbstractExcel excel = getExcel(file);
		return excel.getNumberOfSheets(file);
	}
	
	public static int getSheetBySheetName(File file, String SheetName) throws Exception {
		AbstractExcel excel = getExcel(file);
		return excel.getSheetBySheetName(file, SheetName);
	}
	
	public static int getSheetBySheetName(String fileName,InputStream input, String SheetName) throws Exception {
		AbstractExcel excel = getExcel(fileName);
		return excel.getSheetBySheetName(input, SheetName);
	}
	
}
